﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEditor;

namespace Nirvana
{
    /// <summary>
    /// 用作纹理叠加作UV移动，需要ui/effect shader支持，一般做按键上流光效果
    /// </summary>
    [ExecuteInEditMode]
    [AddComponentMenu("Nirvana/UI/Effects/Overlay Texture")]
    [RequireComponent(typeof(UIMaterialEffect))]
    [DisallowMultipleComponent]
    public class UIOverlayTexture : BaseMeshEffect
    {

        [SerializeField]
        private Texture2D overlayTexture;
        [SerializeField]
        private ColorMode colorMode;
        [SerializeField]
        private TextureMode textureMode;
        [SerializeField]
        [Range(0f, 1f)]
        private float speed;

        private UIMaterialEffect _uieffect;

        public override void ModifyMesh(VertexHelper vh)
        {
            if (!this.IsActive() || vh.currentVertCount <= 0)
            {
                return;
            }

            List<UIVertex> tempList = VertexLists.Get();
            vh.GetUIVertexStream(tempList);
            List<UIVertex> newlist = ModifyTextureVertexs(tempList);
            if (newlist != null)
            {
                vh.Clear();
                vh.AddUIVertexTriangleStream(newlist);
            }
            VertexLists.Set(newlist);
        }

#if UNITY_EDITOR
        protected override void OnValidate()
        {
            ModifyUIEffect();
            if(base.graphic != null)
            {
                base.graphic.SetVerticesDirty();
            }
        }
#endif

        protected override void OnEnable()
        {
            base.OnEnable();
            ModifyUIEffect();
        }

        protected override void OnDisable()
        {
            base.OnDisable();
            if(this._uieffect != null)
            {
                MaterialsEffect materialsEffect = this._uieffect.MaterialsEffect;
                materialsEffect.texture = this.overlayTexture;
                this._uieffect.MaterialsEffect = materialsEffect;
                this._uieffect.Save();
            }
        }

        private void ModifyUIEffect()
        {
#if UNITY_EDITOR
            PrefabType prefabType = PrefabUtility.GetPrefabType(gameObject);
            if(prefabType == PrefabType.Prefab)
            {
                return;
            }
#endif

            if(this._uieffect == null)
            {
                this._uieffect = this.GetOrAddComponent<UIMaterialEffect>();
            }

            MaterialsEffect materialsEffect = this._uieffect.MaterialsEffect;
            materialsEffect.texture = this.overlayTexture;
            materialsEffect.OverlayColorMode = this.colorMode;
            materialsEffect.overlaySpeed = this.speed;
            this._uieffect.MaterialsEffect = materialsEffect;
            this._uieffect.Save();

        }

        private List<UIVertex> ModifyTextureVertexs(List<UIVertex> _list)
        {
            int totalCount = _list.Count;
            if(this.textureMode == TextureMode.GlobalTextArea || this.textureMode == TextureMode.GlobalFullRect)
            {
                Vector2 topLeft = Vector2.zero;
                Vector2 botRight = Vector2.zero;
                if(this.textureMode == TextureMode.GlobalFullRect)
                {
                    RectTransform rectTransform = this.transform as RectTransform;
                    Rect rect = rectTransform.rect;
                    topLeft = new Vector2(rect.xMin, rect.yMax);
                    botRight = new Vector2(rect.xMax, rect.yMin);
                }
                else
                {
                    topLeft = _list[0].position;
                    botRight = _list[_list.Count - 1].position;
                    for (int i = 0; i < _list.Count; i++)
                    {
                        if (_list[i].position.x < topLeft.x)
                        {
                            topLeft.x = _list[i].position.x;
                        }
                        if (_list[i].position.y > topLeft.y)
                        {
                            topLeft.y = _list[i].position.y;
                        }

                        if (_list[i].position.x > botRight.x)
                        {
                            botRight.x = _list[i].position.x;
                        }
                        if (_list[i].position.y < botRight.y)
                        {
                            botRight.y = _list[i].position.y;
                        }
                    }

                }

                float distX = botRight.x - topLeft.x;
                float distY = topLeft.y - botRight.y;
                for (int i = 0; i < totalCount; i++)
                {
                    UIVertex vertex = _list[i];
                    vertex.uv1 = new Vector2((vertex.position.x - topLeft.x) / distX, 1f - (topLeft.y - vertex.position.y) / distY);
                    _list[i] = vertex;
                }
            }
            else
            {
                for (int i = 0; i < totalCount; i++)
                {
                    UIVertex vertex = _list[i];
                    vertex.uv1 = new Vector2((float)((i%6 != 0 && i%6!=5 && i%6 !=4)?1:0),(float)((i % 6 != 2 && i % 6 != 3 && i % 6 != 4) ? 1 : 0));
                    _list[i] = vertex;
                }
            }
            return _list;
        }

    }
}

